
#pragma once
#include <vector>
#include <set>
#include <memory>
#include <atomic>
#include <functional>

#include <boost/asio/awaitable.hpp>

#include "media_sink.hpp"

namespace mms {
    class Codec;
    class ThreadWorker;
    class FlvTag;

    class FlvMediaSink : public MediaSink {
    public:
        FlvMediaSink(ThreadWorker* worker);
        virtual ~FlvMediaSink();
        virtual bool init();
        bool on_metadata(std::shared_ptr<FlvTag> metadata_pkt);
        virtual bool on_audio_packet(std::shared_ptr<FlvTag> audio_pkt);
        virtual bool on_video_packet(std::shared_ptr<FlvTag> video_pkt);
        virtual boost::asio::awaitable<bool> send_flv_tag(std::shared_ptr<FlvTag> pkt);
        void wakeup();
        void on_flv_tag(const std::function<boost::asio::awaitable<bool>(std::vector<std::shared_ptr<FlvTag>>& msgs)>& cb);
        void close();
    protected:
        int64_t last_send_pkt_index_ = -1;
        bool has_video_;
        bool has_audio_;
        bool stream_ready_;
        bool working_ = false;
        std::function<boost::asio::awaitable<bool>(std::vector<std::shared_ptr<FlvTag>>& msgs)> cb_;
        std::function<bool(std::shared_ptr<Codec> video_codec, std::shared_ptr<Codec> audio_codec)> ready_cb_;
    };
};